apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: d8allowedvolumetypes
  labels:
    heritage: deckhouse
    module: admission-policy-engine
    security.deckhouse.io: security-policy
  annotations:
    metadata.gatekeeper.sh/title: "Volume Types"
    description: >-
      Restricts mountable volume types to those specified by the user.
      Corresponds to the `volumes` field in a PodSecurityPolicy. For more
      information, see https://kubernetes.io/docs/concepts/security/pod-security-standards/
spec:
  crd:
    spec:
      names:
        kind: D8AllowedVolumeTypes
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          type: object
          description: >-
            Restricts mountable volume types to those specified by the user.
            Corresponds to the `volumes` field in a PodSecurityPolicy. For more
            information, see https://kubernetes.io/docs/concepts/security/pod-security-standards/
          properties:
            volumes:
              description: "`volumes` is an array of volume types. All volume types can be enabled using `*`."
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package d8.security_policies

        violation[{"msg": msg, "details": {}}] {
            volume_fields := {x | input.review.object.spec.volumes[_][x]; x != "name"}
            field := volume_fields[_]
            not input_volume_type_allowed(field)
            msg := sprintf("The volume type %v is not allowed, pod: %v. Allowed volume types: %v", [field, input.review.object.metadata.name, input.parameters.volumes])
        }

        # * may be used to allow all volume types
        input_volume_type_allowed(field) {
            input.parameters.volumes[_] == "*"
        }

        input_volume_type_allowed(field) {
            field == input.parameters.volumes[_]
        }
